Conditions | 1 |
Paths | 1 |
Total Lines | 396 |
Lines | 0 |
Ratio | 0 % |
Changes | 5 | ||
Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | /** global: Hammer */ |
||
26 | function ImagesCompare(element, options) { |
||
27 | element = $(element); |
||
28 | options = $.extend({}, defaults, options); |
||
29 | options.roundFactor = parseInt('1' + stringRepeat('0', options.precision)); |
||
30 | |||
31 | this._name = pluginName; |
||
32 | |||
33 | var frontElement, backElement, separator, dragHandle, lastRatio = 1, size = { |
||
34 | width: 0, |
||
35 | height: 0, |
||
36 | maxWidth: 0, |
||
37 | maxHeight: 0 |
||
38 | }, events = { |
||
39 | initialised: "imagesCompare:initialised", |
||
40 | changed: "imagesCompare:changed", |
||
41 | resized: "imagesCompare:resized" |
||
42 | }; |
||
43 | |||
44 | function onImagesLoaded() { |
||
45 | var images = element.find('img'), |
||
46 | totalImagesCount= images.length, |
||
47 | elementsLoaded = 0; |
||
48 | |||
49 | function onImageLoaded(){ |
||
50 | if (elementsLoaded >= totalImagesCount) { |
||
51 | init(); |
||
52 | } |
||
53 | } |
||
54 | |||
55 | images.each(function() { |
||
56 | // Image already loaded (cached) |
||
57 | if ($(this)[0].complete) { |
||
58 | totalImagesCount--; |
||
59 | onImageLoaded(); |
||
60 | } else { |
||
61 | // Image loading / error |
||
62 | $(this).load(function() { |
||
63 | elementsLoaded++; |
||
64 | onImageLoaded(); |
||
65 | }); |
||
66 | $(this).error(function() { |
||
67 | elementsLoaded++; |
||
68 | onImageLoaded(); |
||
69 | }); |
||
70 | } |
||
71 | }); |
||
72 | } |
||
73 | |||
74 | onImagesLoaded(); |
||
75 | |||
76 | function init() { |
||
77 | updateDom(); |
||
78 | patchSize(); |
||
79 | initInteractions(); |
||
80 | |||
81 | $(frontElement).attr('ratio', options.initVisibleRatio); |
||
82 | setVisibleRatio(options.initVisibleRatio); |
||
83 | |||
84 | // Let the world know we have done the init |
||
85 | element.trigger({ |
||
86 | type: events.initialised |
||
87 | }); |
||
88 | } |
||
89 | |||
90 | function addResize() { |
||
91 | $(window).on('resize', function (event) { |
||
92 | frontElement.css('clip', ''); |
||
93 | patchSize(); |
||
94 | setVisibleRatio(lastRatio); |
||
95 | |||
96 | // Let the world know we have done some resize updates |
||
97 | element.trigger({ |
||
98 | type: events.resized, |
||
99 | originalEvent: event |
||
100 | }); |
||
101 | }); |
||
102 | } |
||
103 | |||
104 | function initInteractions() { |
||
105 | options.interactionMode = options.interactionMode.toLowerCase(); |
||
106 | |||
107 | if (options.interactionMode != "drag" && options.interactionMode != "mousemove" && options.interactionMode != "click") { |
||
108 | console.warn('No valid interactionMode found, valid values are "drag", "mousemove", "click"'); |
||
109 | } |
||
110 | |||
111 | switch (options.interactionMode) { |
||
112 | case "drag": |
||
113 | initDrag(); |
||
114 | break; |
||
115 | case "mousemove": |
||
116 | initMouseMove(); |
||
117 | break; |
||
118 | case "click": |
||
119 | initClick(); |
||
120 | break; |
||
121 | default: |
||
122 | initDrag(); |
||
123 | } |
||
124 | } |
||
125 | |||
126 | function initDrag() { |
||
127 | if (typeof Hammer == 'undefined') { |
||
128 | console.error('Please include the hammerjs library for drag support'); |
||
129 | } |
||
130 | addDrag(); |
||
131 | addResize(); |
||
132 | } |
||
133 | |||
134 | function initMouseMove() { |
||
135 | addMouseMove(); |
||
136 | addResize(); |
||
137 | } |
||
138 | |||
139 | function initClick() { |
||
140 | addClick(); |
||
141 | addResize(); |
||
142 | } |
||
143 | |||
144 | function addClick() { |
||
145 | element.on('click', function (event) { |
||
146 | var ratio = getElementRatio(event.pageX); |
||
147 | setVisibleRatio(ratio); |
||
148 | }); |
||
149 | } |
||
150 | |||
151 | function addMouseMove() { |
||
152 | var lastMove = 0; |
||
153 | var eventThrottle = 1; |
||
154 | element.on('mousemove', function (event) { |
||
155 | event.preventDefault(); |
||
156 | var now = Date.now(); |
||
157 | if (now > lastMove + eventThrottle) { |
||
158 | lastMove = now; |
||
159 | var ratio = getElementRatio(event.pageX); |
||
160 | setVisibleRatio(ratio); |
||
161 | } |
||
162 | }); |
||
163 | |||
164 | element.on('mouseout', function (event) { |
||
165 | var ratio = getElementRatio(event.pageX); |
||
166 | setVisibleRatio(ratio); |
||
167 | }); |
||
168 | } |
||
169 | |||
170 | function addDrag() { |
||
171 | var hammertime = new Hammer(element[0]); |
||
172 | hammertime.get('pan').set({direction: Hammer.DIRECTION_HORIZONTAL}); |
||
173 | hammertime.on('pan', function (event) { |
||
174 | var ratio = getElementRatio(event.srcEvent.pageX); |
||
175 | setVisibleRatio(ratio); |
||
176 | }); |
||
177 | } |
||
178 | |||
179 | function updateDom() { |
||
180 | element.addClass('images-compare-container'); |
||
181 | element.css('display', 'inline-block'); |
||
182 | |||
183 | frontElement = element.find('> *:nth-child(1)'); |
||
184 | backElement = element.find('> *:nth-child(2)'); |
||
185 | |||
186 | frontElement.addClass("images-compare-before"); |
||
187 | frontElement.css('display', 'block'); |
||
188 | backElement.addClass("images-compare-after"); |
||
189 | backElement.css('display', 'block'); |
||
190 | |||
191 | if (options.addDragHandle) { |
||
192 | buildDragHandle(); |
||
193 | } |
||
194 | |||
195 | if (options.addSeparator) { |
||
196 | buildSeparator(); |
||
197 | } |
||
198 | } |
||
199 | |||
200 | function buildSeparator() { |
||
201 | element.prepend("<div class='images-compare-separator'></div>"); |
||
202 | separator = element.find(".images-compare-separator"); |
||
203 | |||
204 | } |
||
205 | |||
206 | function buildDragHandle() { |
||
207 | element.prepend("<div class='images-compare-handle'></div>"); |
||
208 | dragHandle = element.find(".images-compare-handle"); |
||
209 | dragHandle.append("<span class='images-compare-left-arrow'></span>"); |
||
210 | dragHandle.append("<span class='images-compare-right-arrow'></span>"); |
||
211 | } |
||
212 | |||
213 | function patchSize() { |
||
214 | var imgRef = backElement.find('img').first(); |
||
215 | setSize(imgRef.width(), imgRef.height(), imgRef.naturalWidth(), imgRef.naturalHeight()); |
||
216 | element.css('max-width', size.maxWidth + 'px'); |
||
217 | element.css('max-height', size.maxHeight + 'px'); |
||
218 | frontElement.width(size.width); |
||
219 | frontElement.height(size.height); |
||
220 | } |
||
221 | |||
222 | /** |
||
223 | * |
||
224 | * @param x |
||
225 | * @return float |
||
226 | */ |
||
227 | function getElementRatio(x) { |
||
228 | return roundRatio((x - element.offset().left) / frontElement.width()); |
||
229 | } |
||
|
|||
230 | |||
231 | /** |
||
232 | * |
||
233 | * @param ratio |
||
234 | * @return float |
||
235 | */ |
||
236 | function roundRatio(ratio) { |
||
237 | ratio = Math.round((ratio * options.roundFactor)) / options.roundFactor; |
||
238 | if (ratio > 1) { |
||
239 | ratio = 1; |
||
240 | } |
||
241 | |||
242 | if (ratio < 0) { |
||
243 | ratio = 0; |
||
244 | } |
||
245 | |||
246 | return ratio; |
||
247 | |||
248 | } |
||
249 | |||
250 | /** |
||
251 | * Animation request |
||
252 | * |
||
253 | * @param startValue float |
||
254 | * @param endValue float |
||
255 | * @param duration value in ms |
||
256 | * @param easing linear or swing |
||
257 | */ |
||
258 | function launchAnimation(startValue, endValue, duration, easing) { |
||
259 | $(frontElement).attr('ratio', startValue).animate({ratio: startValue}, { |
||
260 | duration: 0 |
||
261 | }); |
||
262 | |||
263 | $(frontElement).stop().attr('ratio', startValue).animate({ratio: endValue}, { |
||
264 | duration: duration, |
||
265 | easing: easing, |
||
266 | step: function (now) { |
||
267 | var width = getRatioValue(now); |
||
268 | lastRatio = now; |
||
269 | frontElement.attr('ratio', now).css('clip', 'rect(0, ' + width + 'px, ' + size.height + 'px, 0)'); |
||
270 | |||
271 | if (options.addSeparator) { |
||
272 | separator.css('left', width + 'px'); |
||
273 | } |
||
274 | |||
275 | if (options.addDragHandle) { |
||
276 | dragHandle.css('left', width + 'px'); |
||
277 | } |
||
278 | }, |
||
279 | done: function (animation, jumpedToEnd) { |
||
280 | var ratio = $(frontElement).attr('ratio'); |
||
281 | // Let the world know something has changed |
||
282 | element.trigger({ |
||
283 | type: events.changed, |
||
284 | ratio: ratio, |
||
285 | value: getRatioValue(ratio), |
||
286 | animate: true, |
||
287 | animation : animation, |
||
288 | jumpedToEnd: jumpedToEnd |
||
289 | }); |
||
290 | } |
||
291 | }); |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * Get value to reach, based on a ratio |
||
296 | * |
||
297 | * @param ratio float |
||
298 | * @return {number} |
||
299 | */ |
||
300 | function getRatioValue(ratio) { |
||
301 | ratio = Math.round((ratio * options.roundFactor)) / options.roundFactor; |
||
302 | return Math.round(frontElement.width() * ratio); |
||
303 | } |
||
304 | |||
305 | /** |
||
306 | * Change visible ratio |
||
307 | * |
||
308 | * @param ratio float |
||
309 | * @param animate boolean Do we want an animation ? |
||
310 | * @param duration in ms |
||
311 | * @param easing 'swing', 'linear' |
||
312 | */ |
||
313 | function setVisibleRatio(ratio, animate, duration, easing) { |
||
314 | if (typeof animate == 'undefined') { |
||
315 | animate = false; |
||
316 | } |
||
317 | |||
318 | var width = getRatioValue(ratio); |
||
319 | |||
320 | if (animate) { |
||
321 | var finalDuration = duration ? duration : options.animationDuration; |
||
322 | var finalEasing = easing ? easing : options.animationEasing; |
||
323 | |||
324 | launchAnimation(lastRatio, ratio, finalDuration, finalEasing); |
||
325 | |||
326 | // Let the world know something has changed |
||
327 | if (lastRatio != ratio) { |
||
328 | element.trigger({ |
||
329 | type: events.changed, |
||
330 | ratio: lastRatio, |
||
331 | value: width, |
||
332 | animate: animate |
||
333 | }); |
||
334 | } |
||
335 | |||
336 | return; |
||
337 | |||
338 | } else { |
||
339 | frontElement.stop().css('clip', 'rect(0, ' + width + 'px, ' + size.height + 'px, 0)'); |
||
340 | |||
341 | if (options.addSeparator) { |
||
342 | $(separator).stop().css('left', width + 'px'); |
||
343 | } |
||
344 | |||
345 | if (options.addDragHandle) { |
||
346 | dragHandle.css('left', width + 'px'); |
||
347 | } |
||
348 | } |
||
349 | |||
350 | // Let the world know something has changed |
||
351 | if (lastRatio != ratio) { |
||
352 | element.trigger({ |
||
353 | type: events.changed, |
||
354 | ratio: ratio, |
||
355 | value: width, |
||
356 | animate: animate |
||
357 | }); |
||
358 | } |
||
359 | |||
360 | lastRatio = ratio; |
||
361 | } |
||
362 | |||
363 | function setSize(width, height, maxWidth, maxHeight) { |
||
364 | if (typeof width != 'undefined') { |
||
365 | setWidth(width); |
||
366 | } |
||
367 | if (typeof height != 'undefined') { |
||
368 | setHeight(height); |
||
369 | } |
||
370 | if (typeof maxWidth != 'undefined') { |
||
371 | setMaxWidth(maxWidth); |
||
372 | } |
||
373 | if (typeof maxHeight != 'undefined') { |
||
374 | setMaxHeight(maxHeight); |
||
375 | } |
||
376 | return size; |
||
377 | } |
||
378 | |||
379 | function setWidth(width) { |
||
380 | size.width = width; |
||
381 | return size; |
||
382 | } |
||
383 | |||
384 | function setMaxWidth(maxWidth) { |
||
385 | size.maxWidth = maxWidth; |
||
386 | return size; |
||
387 | } |
||
388 | |||
389 | function setHeight(height) { |
||
390 | size.height = height; |
||
391 | return size; |
||
392 | } |
||
393 | |||
394 | function setMaxHeight(maxHeight) { |
||
395 | size.maxHeight = maxHeight; |
||
396 | return size; |
||
397 | } |
||
398 | |||
399 | // public function declaration |
||
400 | // returning element to preserve chaining |
||
401 | return { |
||
402 | "setValue": function (ratio, animate, duration, easing) { |
||
403 | setVisibleRatio(ratio, animate, duration, easing); |
||
404 | return element; |
||
405 | }, |
||
406 | "getValue": function () { |
||
407 | return lastRatio; |
||
408 | }, |
||
409 | "on": function (eventName, callback) { |
||
410 | element.on(eventName, callback); |
||
411 | return element; |
||
412 | }, |
||
413 | "off": function (eventName, callback) { |
||
414 | element.off(eventName, callback); |
||
415 | return element; |
||
416 | }, |
||
417 | "events": function () { |
||
418 | return events; |
||
419 | } |
||
420 | }; |
||
421 | } |
||
422 | |||
472 |